<?php

    #-------------------------------------------------------------#
	# This file is part of the Tekuna MVC Microframework for PHP. #
	# (c) 2009 Niels Jäckel <niels.jaeckel@tekuna.org>            #
	# Please visit http://tekuna.org/ for more information.       #
	#                                                             #
	# This software is licensed under the MIT License. Please     #
	# view the LICENSE file for the full text of this license.    #
    #-------------------------------------------------------------#


	// include all exceptions that will be routed by the error handler
	require_once TEKUNA_ROOT .'org/tekuna/base/exceptions/TekunaException.class.php';
	require_once TEKUNA_ROOT .'org/tekuna/base/exceptions/AbstractPHPErrorException.abstract.php';
	require_once TEKUNA_ROOT .'org/tekuna/base/exceptions/PHPNoticeException.class.php';
	require_once TEKUNA_ROOT .'org/tekuna/base/exceptions/PHPWarningException.class.php';
	require_once TEKUNA_ROOT .'org/tekuna/base/exceptions/PHPUserErrorException.class.php';
	require_once TEKUNA_ROOT .'org/tekuna/base/exceptions/PHPUserWarningException.class.php';
	require_once TEKUNA_ROOT .'org/tekuna/base/exceptions/PHPUserNoticeException.class.php';
	require_once TEKUNA_ROOT .'org/tekuna/base/exceptions/PHPStrictException.class.php';
	require_once TEKUNA_ROOT .'org/tekuna/base/exceptions/PHPRecoverableErrorException.class.php';
	require_once TEKUNA_ROOT .'org/tekuna/base/exceptions/PHPDeprecatedException.class.php';
	require_once TEKUNA_ROOT .'org/tekuna/base/exceptions/PHPUserDeprecatedException.class.php';



	// if PHP < 5.3 some of the error constants doesn't exist.
	if (! defined('E_DEPRECATED')) {

		define('E_DEPRECATED', 16384);
	}

	if (! defined('E_USER_DEPRECATED')) {

		define('E_USER_DEPRECATED', 16384);
	}


	/**
	 * PHP Error handler
	 *
	 * Converts incoming errors into exceptions and throws them.
	 * Then they are handled with the exception handler
	 */

	function TekunaErrorHandler($iSeverity, $sMessage, $sFile, $iLine) {

		// check the current reporting bitmap
		$bHandleError = error_reporting() & $iSeverity;
		if (! $bHandleError) {

			return;
		}

		// get error code name
		$sExceptionClass = 'Exception';
		switch ($iSeverity) {

			case E_NOTICE: $sExceptionClass = 'PHPNoticeException'; break;
			case E_WARNING: $sExceptionClass = 'PHPWarningException'; break;
			case E_USER_ERROR: $sExceptionClass = 'PHPUserErrorException'; break;
			case E_USER_WARNING: $sExceptionClass = 'PHPUserWarningException'; break;
			case E_USER_NOTICE: $sExceptionClass = 'PHPUserNoticeException'; break;
			case E_STRICT: $sExceptionClass = 'PHPStrictException'; break;
			case E_RECOVERABLE_ERROR: $sExceptionClass = 'PHPRecoverableErrorException'; break;
			case E_DEPRECATED: $sExceptionClass = 'PHPDeprecatedException'; break;
			case E_USER_DEPRECATED: $sExceptionClass = 'PHPUserDeprecatedException'; break;
		}

		// throw special exception with the severity as error code
		throw new $sExceptionClass($sMessage, NULL, $iSeverity);
	}


	/**
	 * PHP Exception handler
	 *
	 * Handles uncaught exceptions.
	 */

	function TekunaExceptionHandler(Exception $objException) {

		// log this exception
		log_exception($objException);

		// error header
		// the @ in this place prevents this function of infinite loops if the headers are already sent
		@header('HTTP/1.1 500 Internal Server Error');

		// build a nice HTML output
		echo TekunaException :: getXHTMLOutput($objException);
	}


	// install handlers
	set_error_handler('TekunaErrorHandler');
	set_exception_handler('TekunaExceptionHandler');


	/**
	 * Simple logging function that loggs a given exception to a logfile.
	 * The target file is [APPLICATION_ROOT]/log/exceptions.log
	 */

	function log_exception(Exception $objException) {

		// create instance of a simple logger for the exceptions log file
		$objLogger = new SimpleLogger(APPLICATION_ROOT .'log/exceptions.log');

		// use the static formatter function of the TekunaException to make
		// a nice output for the log file
		$objLogger -> log(TekunaException :: getTextOutput($objException));
	}



	/**
	 * Autoload function to cover not defined classes. Invokes the Exception Handler explicitly.
	 */

	function __autoload($sClassName) {

		// create dummy class
		eval("class $sClassName {}");

		// throw class not found exception
		throw new ClassNotFoundException("Class $sClassName not found.");
	}



	/**
	 * Checks if the given array has numeric indices. If strict mode is enabled,
	 * ALL keys must be integer, else the function returns TRUE if at least one
	 * key is numeric.
	 *
	 * @param array $arrTest the array for testing
	 * @param boolean $bStrict optional;
	 * @return boolean numeric or not
	 */

	function array_is_numeric(array &$arrTest, $bStrict = FALSE) {

		$bIntKeyExists = FALSE;
		$bStringKeyExists = FALSE;

		foreach ($arrTest as $mKey => $_) {

			if (is_int($mKey)) {

				$bIntKeyExists = TRUE;
			}
			else {

				$bStringKeyExists = TRUE;
			}
		}

		if ($bStrict) {

			return ! $bStringKeyExists;
		}
		else {

			return $bIntKeyExists;
		}
	}


